package com.qire.common.utils;

import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheEntity;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.cookie.CookieJarImpl;
import com.lzy.okgo.cookie.store.SPCookieStore;
import com.lzy.okgo.https.HttpsUtils;
import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
import com.lzy.okgo.model.HttpHeaders;
import com.qire.common.SummerApp;
import com.qire.common.BuildConfig;
import com.qire.common.basic.ObjectUtil;
import com.qire.common.basic.StringUtil;
import com.qire.common.constant.Url;
import com.qire.common.model.entity.UserEntity;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import okhttp3.OkHttpClient;

/**
 * OkGoHttp 全局初始化配置助手
 */
public class OkGoConfigHelper {

    /** 登录口令，登录时服务器给的Token口令，需要在登录时修改 */
    private static final String HeaderKeyToken = "qrmh-token";
    /** 客户端类型：android */
    private static final String HeaderKeyClient = "qrmh-client";
    /** app当前版本名称 */
    private static final String HeaderKeyVersionName = "qrmh-version";
    /** app当前版本代码 */
    private static final String HeaderKeyVersionCode = "qrmh-version-code";
    /** app当前发行渠道号 */
    private static final String HeaderKeyChannel = "qrmh-channel";
    /** app随机生成UUID，生成后会缓存到本地，如果可以拿到 IEMI 则使用IEMI */
    private static final String HeaderKeyUUID = "qrmh-uuid";
    /** 网页来源，用于从内嵌网页打开支付。 */
    private static final String HeaderKeyReferer = "referer";

    /** 用于缓存HTTP请求头数据信息。 */
    public static final HashMap<String, String> headerMap = new HashMap<>(7);

    /**
     * 生成随机UUID号并缓存UUID到本地
     * @return 如果本地已存在，则直接返回存在的。
     */
    private static String generateRandomUUID() {
        String uuid_key = "uuid";
        String strUUID = CacheStorageUtil.queryString(uuid_key);
        if(StringUtil.isEmpty(strUUID)) {
            strUUID = UUID.randomUUID().toString();
            CacheStorageUtil.save(uuid_key, strUUID);
        }
        return strUUID;
    }

    /**
     * 初始化HTTP请求头数据, 虽然下面三个参数都是全局的，因为提交商店的合规检查导致初始化需要延时，
     * 为了保持初始化先后顺序，将参数抽离出去，这样可以保证在使用时能提醒初始化的先后顺序依赖
     * @param versionName 版本名
     * @param versionCode 版本代码
     * @param channel 渠道
     */
    public static void initHeader(String versionName, int versionCode, String channel) {
        headerMap.put(HeaderKeyToken, UserEntity.self.getToken());
        headerMap.put(HeaderKeyClient, "android");
        headerMap.put(HeaderKeyVersionName, versionName);
        headerMap.put(HeaderKeyVersionCode, String.valueOf(versionCode));
        headerMap.put(HeaderKeyChannel, channel);
        headerMap.put(HeaderKeyUUID, generateRandomUUID());
        headerMap.put(HeaderKeyReferer, Url.domain_m);
    }

    /**
     * 初始化 OKGO HTTP 请求全局配置信息
     * @param summerApp APP 实例
     */
    public static void initOkGo(SummerApp summerApp) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        if(BuildConfig.DEBUG) {
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
            //log打印级别，决定了log显示的详细程度
            loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
            //log颜色级别，决定了log在控制台显示的颜色
            loggingInterceptor.setColorLevel(Level.INFO);
            builder.addInterceptor(loggingInterceptor);
        }

        //全局的读取超时时间
        builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
        //全局的写入超时时间
        builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
        //全局的连接超时时间
        builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);

        //使用sp保持cookie，如果cookie不过期，则一直有效
        builder.cookieJar(new CookieJarImpl(new SPCookieStore(summerApp)));

        //信任所有证书,不安全有风险
        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);

        HttpHeaders headers = new HttpHeaders();
        for (Map.Entry<String, String> entry : headerMap.entrySet()) {
            headers.put(entry.getKey(), entry.getValue());
        }

        OkGo.getInstance().init(summerApp)                            //必须调用初始化
                .setOkHttpClient(builder.build())               //必须设置OkHttpClient
                .setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式，默认不使用缓存，可以不传
                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间，默认永不过期，可以不传
                .setRetryCount(3)                               //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
                .addCommonHeaders(headers);                     //全局公共头

    }

    /**
     * 刷新请求头Token
     */
    public static void refreshToken() {
        if(ObjectUtil.nonNull(headerMap)) {
            headerMap.put(HeaderKeyToken, UserEntity.self.getToken());
        }

        HttpHeaders headers = OkGo.getInstance().getCommonHeaders();
        if(ObjectUtil.isNull(headers)) {
            headers = new HttpHeaders();
            headers.put(HeaderKeyToken, UserEntity.self.getToken());
            OkGo.getInstance().addCommonHeaders(headers);
        }else{
            headers.put(HeaderKeyToken, UserEntity.self.getToken());
        }
    }

    /**
     * 需要授权才能获取到
     */
    public  static void setDeviceUuidWithImei(String imei) {

        if (StringUtil.isEmpty(imei) || imei.equals("000000000000000")) {
            return;
        }

        if(ObjectUtil.nonNull(headerMap)) {
            headerMap.put(HeaderKeyUUID, imei);
        }

        HttpHeaders headers = OkGo.getInstance().getCommonHeaders();
        if(ObjectUtil.isNull(headers)) {
            headers = new HttpHeaders();
            headers.put(HeaderKeyUUID, imei);
            OkGo.getInstance().addCommonHeaders(headers);
        }else{
            headers.put(HeaderKeyUUID, imei);
        }

    }


}
